package PartEdgeDemo;

import java.awt.Color;
import java.awt.geom.Ellipse2D;

import y.base.Edge;
import y.base.EdgeCursor;
import y.base.EdgeList;
import y.base.Graph;
import y.base.Node;
import y.base.NodeCursor;
import y.geom.LineSegment;
import y.geom.YPoint;
import y.layout.EdgeLayout;
import y.layout.NodeLayout;
import y.view.EdgeRealizer;
import y.view.Graph2D;
import y.view.HitInfo;
import y.view.ShapeDrawable;
import y.view.View;



public class SpringEmbedder {
	
	  final View v;
	  public int factor;

	  public SpringEmbedder(View v, int factor) {
	    this.v = v;
	    this.factor = factor;
	  }

	  public View runAlgorithm(){
		  
		  Graph2D g = v.getGraph2D();
		  Node[] nodes = g.getNodeArray();
		  Edge[] alledges = g.getEdgeArray();
		  boolean somethingmoved = true;
		  int counter = 0;
		  
		  while(!somethingmoved && (counter<10)){
			  somethingmoved = false;
		      counter++;
			  for(int i=0; i<nodes.length; i++){
				  Node n = nodes[i];
				  boolean hascrossings = false;
				  Edge[] incidents = getIncidentEdges(n,v);
				  for(int j=0; j<incidents.length; j++){
					  Edge e = incidents[j];
					  for(int k=0; k<alledges.length; k++){
						  if (alledges[k] != e){
							  if (checkcrossing(e,alledges[k],v)){
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  //TODO: gute Strategie
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  
								  hascrossings = true;
							  }
						  }
					  }
					  // ende e mit alle Kanten getestet 
				  }
				  // end alle Kanten von n getestet -> e.source=n verschieben
				  
				  NodeLayout nl = g.getNodeLayout(n);
				  if(hascrossings == true){
					  somethingmoved = true;
					  // nl.setLocation(0,0); // Knoten muss hier verschoben werden gemäß Gewichten
				  }
				  // Dunmmy-werte müssen noch ersetzt werden
				  //nl.setLocation(nl.getX()+n.inDegree(), nl.getY()+n.inDegree());
	          }
			  //alle Knoten sind getestet
		  }
		  
		  return this.v;
	    
	  }
	  
	  private Edge[] getIncidentEdges(Node n, View v){
		  Edge[] e = v.getGraph2D().getEdgeArray();
		  Edge[] result = new Edge[n.inDegree()+n.outDegree()];
		  int j=0;
		  for(int i=0; i<e.length; i++){
			  if(e[i].source()==n || e[i].target()==n){
				  result[j]=e[i];
				  j++;
			  }
		  }
		  return result;
	  }
	  
	  private boolean checkcrossing(Edge e, Edge f, View v){
	    //System.out.println(e.toString()+f.toString());
	    //checkt nur, ob Kreuzungen im nicht-legalen Bereich sind, d.h. außerhalb der mittleren 2 viertel
	    boolean result = false;

	    EdgeRealizer firstER = v.getGraph2D().getRealizer(e);
	    EdgeRealizer secondER = v.getGraph2D().getRealizer(f);
	    LineSegment firstEdge = new LineSegment(PathOperation.getStartOfPath(firstER.getPath(),true), PathOperation.getStartOfPath(firstER.getPath(), false));
	    LineSegment secondEdge = new LineSegment(PathOperation.getStartOfPath(secondER.getPath(),true), PathOperation.getStartOfPath(secondER.getPath(), false));

	    YPoint intersection = LineSegment.getIntersection(firstEdge, secondEdge);
        if(intersection != null){
      	//check whether an intersection in new model exists
	      if(PathOperation.intersectsWithParts(firstEdge, intersection, factor) && PathOperation.intersectsWithParts(secondEdge, intersection, factor)){
	        result = true;
	      }
	    }
		  return result;
	  }
	  
}
